package pub.yxc1014.context;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pub.yxc1014.annotation.Repository;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public abstract class ApplicationContext {
    protected String context;
    public Object getBean(String beanId){
        return new Object();
    }
    public <T> T getBean(String beanId,Class<T> t){
        SAXReader reader=new SAXReader();
        Document document= null;
        try {
            document = reader.read(context);
            Element root = document.getRootElement();
            //注解式
            Element componentScan = root.element("component-scan");
            String basePackage = componentScan.attributeValue("base-package");
            List<Class<?>> classList=getClasses(basePackage);
            Repository op=null;
            for (Class<?> tz:classList) {
                op = tz.getDeclaredAnnotation(Repository.class);
                if(null!=op&&op.value().equals(beanId)){
                    T t1 = ((Class<T>) tz).newInstance();
                    return t1;
                }
            }
                //配置式
//            List<Element> elements = root.elements("bean");
//            Bean bean=new Bean();
//            for (int i = 0; i < elements.size(); i++) {
//                bean.setId(elements.get(i).attributeValue("id"));
//                bean.setClaz(elements.get(i).attributeValue("clasz"));
//                if(bean.getId().equals(beanId)&&t!=null){
//                    try {
//                        return t.newInstance();
//                    } catch (InstantiationException e) {
//                        e.printStackTrace();
//                    } catch (IllegalAccessException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }

    //获得所有的类的Class
    protected List<Class<?>> getClasses(String basePackage){
        List<Class<?>> classes = new ArrayList<Class<?>>();
        // 是否循环迭代
        boolean recursive = true;
        // 获取包的名字 并进行替换
        String packageDirName = basePackage.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的things
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            // 循环迭代下去
            while (dirs.hasMoreElements()) {
                // 获取下一个元素
                URL url = dirs.nextElement();
                // 得到协议的名称
                String protocol = url.getProtocol();
                // 如果是以文件的形式保存在服务器上
                if ("file".equals(protocol)) {
                    // 获取包的物理路径
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    // 以文件的方式扫描整个包下的文件 并添加到集合中
                    findAndAddClassesInPackageByFile(basePackage, filePath, recursive, classes);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return classes;
    }

    // 查询包下所有的类，并且添加到集合中
    protected void findAndAddClassesInPackageByFile(String basePackage, String filePath, boolean recursive, List<Class<?>> classes){
        // 获取此包的目录 建立一个File
        File dir = new File(filePath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirfiles = dir.listFiles(new FileFilter() {
            // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
            public boolean accept(File file) {
                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
            }
        });
        // 循环所有文件
        for (File file : dirfiles) {
            // 如果是目录 则继续扫描
            if (file.isDirectory()) {
                findAndAddClassesInPackageByFile(basePackage + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
            } else {
                // 如果是java类文件 去掉后面的.class 只留下类名
                String className = file.getName().substring(0, file.getName().length() - 6);
                try {
                    // 添加到集合中去
                    classes.add(Class.forName(basePackage + '.' + className));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
